package org.internna.expensetracker.model.security;

import static org.springframework.util.StringUtils.hasText;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQuery;
import javax.persistence.Query;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.springframework.roo.addon.entity.RooEntity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.serializable.RooSerializable;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

@RooJavaBean
@RooToString
@RooEntity(table = "AUTHORITY_NAMES")
@RooSerializable
@NamedQuery(name = "findByName", query = "SELECT a FROM Authority a WHERE authority = :authority")
public class Authority {

	private static final long serialVersionUID = -8660021272977675242L;

	public static final String ROLE_USER = "ROLE_USER";
	public static final String ROLE_ADMIN = "ROLE_ADMIN";

	@ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
    private Set<UserDetails> users = new HashSet<UserDetails>();

    @NotNull
    @Size(min = 6)
    @Column(unique = true)
    private String authority;

    @Transactional
    public void remove() {
    	if (this.entityManager == null) this.entityManager = entityManager();
    	if (!CollectionUtils.isEmpty(users)) {
    		for (UserDetails user : users) {
    			user.getRoles().remove(this);
    			user.flush();
    		}
    		users.clear();
    		flush();
    	}
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Authority attached = findAuthority(getId());
            this.entityManager.remove(attached);
        }
    }

    public static Authority findByName(String name) {
    	Authority authority = null;
    	if (hasText(name)) {
    		Query query = entityManager().createNamedQuery("findByName");
    		query.setParameter("authority", name);
    		authority = (Authority) query.getSingleResult();
    	}
    	return authority;
    }
}
